import {Vector3} from "../../core/math/Vector3"
import {Quaternion} from "../../core/math/Quaternion"
/**
 * @class
 * @memberof w.parser
 * @param {*} message 消息
 * @param {*} callback 处理完成的回调
 */
function line(message, callback) {
    const {points, capCount, jointCount, lineJoint, isTile} = message;

    // 1. 预计算总大小
    let totalPositions = 0;
    let totalIndices = 0;
    let totalUvFactors = 0;

    for (const item of points) {
        const lineData = genOneLine({points: item, capCount, jointCount, lineJoint, isTile});
        totalPositions += lineData.positions.length;
        totalIndices += lineData.indices_array.length;
        totalUvFactors += lineData.uvWidthFactor.length;
    }

    // 2. 预分配TypedArrays
    const positions = new Float32Array(totalPositions);
    const previous = new Float32Array(totalPositions);
    const next = new Float32Array(totalPositions);
    const indexMap = new Float32Array(totalPositions);
    const indices_array = new Uint32Array(totalIndices);
    const directions = new Float32Array(totalPositions);
    const uvWidthFactor = new Float32Array(totalUvFactors);

    // 3. 存储线段长度信息
    const lineLengthArray = new Array(points.length);
    const lineLengthFactorArray = new Array(points.length);

    // 4. 填充数据
    let posOffset = 0;
    let idxOffset = 0;
    let uvOffset = 0;
    let pointCount = 0;

    for (let i = 0; i < points.length; i++) {
        const lineData = genOneLine({
            points: points[i],
            capCount,
            jointCount,
            lineJoint,
            isTile
        });

        // 批量复制位置相关数据
        positions.set(lineData.positions, posOffset);
        previous.set(lineData.previous, posOffset);
        next.set(lineData.next, posOffset);
        indexMap.set(lineData.indexMap, posOffset);
        directions.set(lineData.directions, posOffset);

        // 处理索引数据
        for (let j = 0; j < lineData.indices_array.length; j++) {
            indices_array[idxOffset + j] = lineData.indices_array[j] + pointCount;
        }

        // 复制UV因子数据
        uvWidthFactor.set(lineData.uvWidthFactor, uvOffset);

        // 存储线段长度信息
        lineLengthArray[i] = lineData.lineLength;
        lineLengthFactorArray[i] = lineData.lineLengthFactor;

        // 更新偏移量
        posOffset += lineData.positions.length;
        idxOffset += lineData.indices_array.length;
        uvOffset += lineData.uvWidthFactor.length;
        pointCount += lineData.positions.length / 3;
    }

    // 5. 创建最终的线段长度数组
    const lineLength = new Float32Array([lineLengthArray]);
    const lineLengthFactor = new Float32Array(lineLengthFactorArray);

    // 6. 返回结果
    callback({
        data: {
            positions,
            previous,
            next,
            indexMap,
            indices_array,
            directions,
            lineLength,
            lineLengthFactor,
            uvWidthFactor
        },
        transferlist: [
            positions.buffer,
            previous.buffer,
            next.buffer,
            indexMap.buffer,
            indices_array.buffer,
            directions.buffer,
            lineLength.buffer,
            lineLengthFactor.buffer,
            uvWidthFactor.buffer
        ]
    });
}
function genOneLine(message) {
    let {points, capCount, jointCount, lineJoint, isTile} = message;
    let positions = [];
    let previous = [];
    let next = [];
    let indexMap = [];
    let indices_array = [];
    let directions = [];
    let lineLength = 0;
    let lineLengthFactor = [0,0];
    let lastCornerInsideLength = 0;
    let lastDirUvSide = 1;
    let lastDir = new Vector3(0,0,0);
    let lastStartIndice = 0;
    let lastEndIndice = 0;
    let uvWidthFactor = [];
    for (var index = 0; index < points.length; index ++) {
        let prevPos = getPrevPos(index, points);
        let nextPos = getNextPos(index, points);
        previous.push(prevPos.x, prevPos.y,prevPos.z, prevPos.x, prevPos.y,prevPos.z);
        next.push(nextPos.x, nextPos.y, nextPos.z, nextPos.x, nextPos.y, nextPos.z);
        let addPointsFunc = (index === 0 || index === points.length - 1) ? addCap : addJoin;
        let {
            positions: linePointPositions,
            indexMap: linePointIndexMap,
            indices_array: linePointIndices,
            startIndex,
            endIndex,
            uvWidthFactor: linePointsUvWidthFactor,
            directions: linePointNormals,
            currentLineLength,
            currentLengthFactor,
            currentCornerInsideLength,
            currentDirUvSide,
            currentDir
        } = addPointsFunc(index, points, prevPos, nextPos, positions.length / 3, lastStartIndice, lastEndIndice, directions, lineLength, lastCornerInsideLength, lastDirUvSide, lastDir, lineLengthFactor,capCount, jointCount, lineJoint, isTile);
        lastStartIndice = startIndex;
        lastEndIndice = endIndex;
        lastDir = currentDir;
        lastDirUvSide = currentDirUvSide;
        lastCornerInsideLength = currentCornerInsideLength;
        positions.push(...linePointPositions);
        indexMap.push(...linePointIndexMap);
        indices_array.push(...linePointIndices);
        uvWidthFactor.push(...linePointsUvWidthFactor);
        directions.push(...linePointNormals);
        lineLengthFactor = [...currentLengthFactor];
        lineLength = currentLineLength;
    }
    let uvWidthFactors = [];
    uvWidthFactor.forEach(item => {
        uvWidthFactors.push(...item)
    })
    return( {
      positions,
      previous,
      next,
      indexMap,
      indices_array,
      directions,
      lineLength,
      lineLengthFactor,
      uvWidthFactor: uvWidthFactors
    });
}
function addCap(index, points, prevPos, nextPos, count, lastStartIndice, lastEndIndice, currentDirections, lineLength, lastCornerInsideLength, lastDirUvSide, lastDir, lineLengthFactor, capCount, jointCount, lineJoint, isTile) {
  let positions = [];
  let indexMap = [];
  let indices_array = []
  let uvWidthFactor = []
  let directions = [];
  let curPos = new Vector3(points[index][0], points[index][1], points[index][2]);
  let currentDirUvSide = -1;
  let centerIndex = count;
  let startIndex = count + 1;
  let endIndex = count + capCount + 2;
  let dir = new Vector3();
  let clock=1;
  let lastEndDirection = new Vector3(currentDirections[lastEndIndice * 3], currentDirections[lastEndIndice * 3 +1], currentDirections[lastEndIndice * 3+2]);
  let prevDir = new Vector3();
  let currentLengthFactor = [...lineLengthFactor];
  prevDir.subVectors(curPos , prevPos);
  let n = new Vector3();
  let dir_v = new Vector3();
  if(index === 0) {
      let temp = new Vector3();
      dir.subVectors(nextPos, curPos).setZ(0).normalize();
      if(points[index+2]) {
        temp.subVectors(new Vector3(points[index+2][0], points[index+2][1], points[index+2][2]), nextPos).setZ(0);
        n.crossVectors(dir, temp).normalize();
        dir_v.crossVectors(n, dir).normalize();
      } else {//线只有两个点，虚拟xy平面上的一条线用于确定面
       temp = new Vector3(dir.x+1,dir.y+1,0);
       temp.normalize();
       let cos = dir.dot(temp);
        if(Math.abs(cos) > 0.99999999) {//若虚拟线与线段共线，重新计算虚拟线
            temp = new Vector3(dir.x+1,dir.y,0);
        }
        n.crossVectors(dir, temp).normalize();
        dir_v.crossVectors(n, dir).normalize();
      }
  } else if(index === points.length - 1) {
      let temp = new Vector3();
      dir.subVectors(curPos, prevPos).setZ(0).normalize();
      if(points[index-2]) {
        temp.subVectors(new Vector3(points[index-1][0], points[index-1][1], points[index-1][2]), new Vector3(points[index-2][0], points[index-2][1], points[index-2][2])).setZ(0).normalize();
        n.crossVectors(dir, temp).normalize();
        dir_v.crossVectors(dir, n).normalize();
      } else {
        temp = new Vector3(dir.x-1,dir.y-1,0);
        temp.normalize()
        let cos = dir.dot( temp);
        if(Math.abs(cos) > 0.999999) {
            temp = new Vector3(dir.x-1,dir.y,0);
        }
        n.crossVectors(dir, temp).normalize();
        dir_v.crossVectors(dir, n).normalize();
      }
  }
  let { collapsedLength1, segmentLength } = getSegmentsLength(lastDir, dir_v, dir_v, curPos, prevPos);
  if(index === points.length - 1 && points.length > 2){
      jointCount = getJoinCount(lineJoint, jointCount)
      let cornerInsidePartLength = (lastCornerInsideLength + Math.abs(collapsedLength1) )/(jointCount + 1);
      for(let i = 0 ; i < jointCount ; i++) {
          uvWidthFactor.push([currentLengthFactor[0], currentLengthFactor[1] - lastCornerInsideLength +  cornerInsidePartLength * (i+1), lastDirUvSide === -1 ? 0 :1, 0])
      }
      uvWidthFactor.push([currentLengthFactor[0], currentLengthFactor[1] + Math.abs(collapsedLength1), lastDirUvSide === -1 ? 0 :1, 0])
  }
  //圆心点
  positions.push(...points[index]);
  indexMap.push(index);
  directions.push(0, 0, 0);
  lineLength += segmentLength;
  currentLengthFactor = [currentLengthFactor[0] + segmentLength, currentLengthFactor[1]]
  uvWidthFactor.push([index === 0 ? 0 :  currentLengthFactor[0], currentLengthFactor[1], 1/2, 0])
  let partAngle = Math.PI / (capCount + 1);
  for(let i = 0 ; i < capCount + 2; i++) {
      positions.push(...points[index]);
      indexMap.push(index);
      if(!isSameSide(lastDir, dir_v, prevDir))  {
          //两夹角角分线在同一侧则uv对应y值相同
          currentDirUvSide = -lastDirUvSide;
      } else {
          currentDirUvSide = lastDirUvSide;
      }
      if(i === 0) {
          uvWidthFactor.push([currentLengthFactor[0], currentLengthFactor[1], currentDirUvSide === -1 ? 0 :1, 0])
      } else if ( i === capCount + 1) {
          uvWidthFactor.push([currentLengthFactor[0], currentLengthFactor[1], currentDirUvSide === -1 ? 1 :0, 0])
          currentDirUvSide = -currentDirUvSide;
      } else {
          let x = Math.abs(Math.sin(partAngle * i) / 2);
          let y = Math.cos(partAngle * i) / 2;
          let flag = index === 0 ? -1 : 1;
          uvWidthFactor.push([currentLengthFactor[0],currentLengthFactor[1] + Math.abs(Math.sin(partAngle * i) / 2)*flag, 1/2 - y, 0])
      }
      let normal = dir_v.clone();
      let roatateQuaternion = new Quaternion();
      roatateQuaternion.setFromAxisAngle(n.clone(),Math.PI / (capCount + 1) * i * clock  )
      normal.applyQuaternion(roatateQuaternion).normalize();
      directions.push(normal.x, normal.y, normal.z);
      if(i < capCount + 1 ) {
        let indexFlag = index === 0 ? -1 : 1;
        let flag = n.z !== 0 ? n.z : n.y !== 0 ? n.y* indexFlag > 0 ? n.y : -n.y : n.x;//待完善
        flag < 0
        ? indices_array.push(centerIndex + i + 1, centerIndex , centerIndex + i + 2)
        : indices_array.push(centerIndex + i + 2, centerIndex , centerIndex + i + 1);
      }
  }
  if(index === points.length - 1) {
    let clock = getClock(
        lastEndDirection,
        prevDir
    );
    if(!isSameSide(lastEndDirection, dir_v, prevDir)) {
        clock > 0
        ? indices_array.push(lastStartIndice, lastEndIndice, centerIndex + 1)
        : indices_array.push(lastStartIndice, centerIndex + 1, lastEndIndice)
        clock > 0
        ? indices_array.push(centerIndex + 1, lastEndIndice, centerIndex + capCount + 2 )
        : indices_array.push(centerIndex + 1,  centerIndex + capCount + 2, lastEndIndice)
    } else {
        clock > 0
        ? indices_array.push(lastStartIndice, lastEndIndice, centerIndex + capCount + 2)
        : indices_array.push(lastStartIndice, centerIndex + capCount + 2, lastEndIndice)
        clock > 0
        ? indices_array.push(lastEndIndice, centerIndex + 1, centerIndex + capCount + 2)
        : indices_array.push(centerIndex + capCount + 2, centerIndex + 1, lastEndIndice)
    }
  }
  return {
      positions,
      indexMap,
      indices_array,
      startIndex,
      endIndex,
      uvWidthFactor,
      directions,
      currentDirUvSide,
      currentLineLength: lineLength,
      currentLengthFactor,
      currentDir: new Vector3(directions[directions.length-3], directions[directions.length-2], directions[directions.length-1]),
      currentCornerInsideLength: 0
  }
}
function addJoin(index, points, prevPos, nextPos, count, lastStartIndice, lastEndIndice, currentDirections, lineLength, lastCornerInsideLength, lastDirUvSide, lastDir, lineLengthFactor, capCount, jointCount, lineJoint, isTile) {
  jointCount = getJoinCount(lineJoint, jointCount)
  let positions = [];
  let indexMap = [];
  let indices_array = []
  let uvWidthFactor = []
  let directions = []
  let startIndex ;
  let endIndex;
  let currentLengthFactor = [...lineLengthFactor];
  let curPos = new Vector3(points[index][0], points[index][1], points[index][2]);
  let {miterDir, firstDir, secondDir, prevDir, cos, clock, normal:rotateAxis} = getJointDirection(curPos, prevPos, nextPos, isTile, index, points);
  let lastEndDirection = new Vector3(currentDirections[lastEndIndice * 3], currentDirections[lastEndIndice * 3 +1], currentDirections[lastEndIndice * 3+2]);
  let { segmentLength,collapsedLength1,collapsedLength2} = getSegmentsLength(lastDir, miterDir, firstDir, curPos, prevPos);
  let currentDirUvSide = 0;
  if(!isSameSide(lastDir, miterDir, prevDir))  {
      currentDirUvSide = -lastDirUvSide;
  } else {
      currentDirUvSide = lastDirUvSide;
  }
  if(index > 1) {
      let cornerInsidePartLength = (lastCornerInsideLength + Math.abs(collapsedLength1) )/(jointCount + 1);
      for(let i = 0 ; i < jointCount ; i++) {
          uvWidthFactor.push([currentLengthFactor[0], currentLengthFactor[1] - lastCornerInsideLength +  cornerInsidePartLength * (i+1), lastDirUvSide === -1 ? 0 :1, 0])
      }
      uvWidthFactor.push([currentLengthFactor[0], currentLengthFactor[1] + Math.abs(collapsedLength1), lastDirUvSide === -1 ? 0 :1, 0])
  }
  lineLength += segmentLength;
  currentLengthFactor = [currentLengthFactor[0] + segmentLength, currentLengthFactor[1]]
  let angle =firstDir.angleTo(secondDir);
  let partAngle = angle/(jointCount + 1);
  let rotateDir = firstDir.clone();
  let cornerLineLength = 0;
  let cornerSumLength = 0;
  //外侧添点
  for(let i = 0 ; i < jointCount + 2 ; i++) {
      positions.push(...points[index]);
      indexMap.push(index);
      uvWidthFactor.push([currentLengthFactor[0],currentLengthFactor[1] + cornerSumLength, currentDirUvSide === -1 ? 1 :0, 0])
      if(lineJoint === 'miter') {
          cornerLineLength = Math.tan(partAngle) / 2  ;
      } else {
          cornerLineLength = Math.sin(partAngle / 2) ;
      }
      if(i < jointCount + 1) {
          cornerSumLength += cornerLineLength ;
      }
      let normal = rotateDir.clone();
      let flag = rotateAxis.z !== 0 ? rotateAxis.z : rotateAxis.y !== 0 ? Math.abs(rotateAxis.y) : rotateAxis.x;//待完善
      flag = flag > 0 ? 1 : -1
      let roatateQuaternion = new Quaternion();
      roatateQuaternion.setFromAxisAngle(new Vector3(flag* rotateAxis.x,flag*rotateAxis.y ,flag*rotateAxis.z),angle / (jointCount + 1) * i * clock  )
      normal.applyQuaternion(roatateQuaternion);

      if(lineJoint === 'miter' && i !== 0 && i !== jointCount + 1) {
          let calcNormal = normal.clone();
        //   cos = cos < 0 ? Math.min(cos, -0.1) : Math.max(cos, 0.1)
        calcNormal.multiplyScalar(Math.abs(1/cos))
          directions.push(calcNormal.x, calcNormal.y, calcNormal.z);
      } else {
          directions.push(normal.x, normal.y, normal.z);
      }
  }
  //内侧添点
  for(let i = 0 ; i < jointCount + 2 ; i++) {
      positions.push(...points[index]);
      indexMap.push(index);
      let calcNormal = miterDir.clone();
      //防止尖角无限大
    //   cos = cos < 0 ? Math.min(cos, -0.1) : Math.max(cos, 0.1)
      calcNormal.multiplyScalar(Math.abs(1/cos))
      directions.push(calcNormal.x, calcNormal.y, calcNormal.z);
      if(index < points.length - 1 && i < jointCount + 1 ) {
        let clock1 = getClock(
            new Vector3(directions[3*i], directions[3*i+1], directions[3*i+2]),
            new Vector3(directions[3*(i+1)], directions[3*(i+1)+1], directions[3*(i+1)+2])
        );
        let clock2 = getClock(
            new Vector3(directions[3*(i + jointCount + 2)], directions[3*(i + jointCount + 2)+1],directions[3*(i + jointCount + 2)+2]),
            new Vector3(directions[3*(i+1)], directions[3*(i+1)+1], directions[3*(i+1)+2])
        )
        clock1 > 0
        ? indices_array.push( count + 1 + i ,count + i + jointCount + 2, count + i)
        : indices_array.push( count + i ,count + i + jointCount + 2, count + 1 + i);
        clock2 < 0
        ?  indices_array.push(count + i + jointCount + 2, count + i + 1, count + i + jointCount + 3 )
        :  indices_array.push(count + i + jointCount + 3, count + i + 1, count + i + jointCount + 2 );
      }
  }
  uvWidthFactor.push([currentLengthFactor[0],currentLengthFactor[1]- Math.abs(collapsedLength2), currentDirUvSide === -1 ? 0 :1, 0])
  if(index < points.length - 1 ) {
    let clock = getClock(
        lastEndDirection,
        prevDir
    );
    if(!isSameSide(lastEndDirection, miterDir, prevDir))  {
        clock > 0
        ? indices_array.push(lastStartIndice, lastEndIndice, count + jointCount + 2 )
        : indices_array.push(lastStartIndice, count + jointCount + 2, lastEndIndice )
        clock > 0
        ? indices_array.push(count + jointCount + 2, lastEndIndice, count )
        : indices_array.push(lastEndIndice, count + jointCount + 2, count )
        startIndex = count + 2*jointCount + 3;
        endIndex = count +jointCount + 1;
      } else {
        clock > 0
        ? indices_array.push(lastStartIndice, lastEndIndice, count )
        : indices_array.push(lastStartIndice, count, lastEndIndice )
        clock > 0
        ? indices_array.push(count, lastEndIndice, count + jointCount + 2 )
        : indices_array.push(count,  count + jointCount + 2, lastEndIndice )
        startIndex = count + jointCount + 1;
        endIndex = count + 2*jointCount + 3;
      }
  }
  let currentCornerInsideLength = cornerSumLength + Math.abs(collapsedLength2);
  lineLength = lineLength + cornerSumLength;
  currentLengthFactor = [currentLengthFactor[0],currentLengthFactor[1] + cornerSumLength]
  return {
      positions,
      indexMap,
      indices_array,
      uvWidthFactor,
      startIndex,
      endIndex,
      directions,
      currentDirUvSide,
      currentLengthFactor,
      currentLineLength: lineLength,
      currentCornerInsideLength,
      currentDir: miterDir
  }
}
function comparePoint(a, b) {
  if(!a || !b) return false;
  return (
      a[0] === b[0] &&
      a[1] === b[1] &&
      a[2] === b[2]
  )
}
function copyPoint(a) {
  return new Vector3(a[0], a[1], a[2])
}
function getJoinCount(lineJoint, jointCount) {
  if(lineJoint === 'miter') {
      return  1;
   } else if (lineJoint === 'bevel') {
      return 0;
   } else if (lineJoint === 'round') {
      return jointCount;
   }
}
function getPrevPos(index, points) {
  let l = points.length;
  let v = [];
  if(index === 0) {
      if (comparePoint(points[0], points[l - 1]) && points[l - 2]) {//第一个点是否和最后一个点相同，若相同，上一个点为倒数第二个点，否则上一个点为第一个点
          v = copyPoint(points[l - 2]);
      } else {
          v = copyPoint(points[0]);
      }
  } else {
      v = copyPoint(points[index - 1]);
  }
  return v;

}
function getNextPos(index, points) {
  let l = points.length;
  let v = [];
  if(index === l - 1) {
      if (comparePoint(points[0], points[l - 1]) && points[1]) {
          v = copyPoint(points[1])
      } else {
          v = copyPoint(points[l - 1])
      }
  } else {
      v = copyPoint(points[index + 1])
  }
  return v;
}
function getSegmentsLength(prevDir, curDir, firstDir, curPos, prevPos) {
  let angle1 = firstDir.angleTo(prevDir);
  let angle2 = firstDir.angleTo(curDir);
  let dir1 = new Vector3();
  dir1.subVectors(curPos , prevPos)
  let segmentLength = dir1.length();
  let collapsedLength1 = Math.abs(Math.tan(angle1)/2);
  let collapsedLength2 = Math.abs(Math.tan(angle2)/2);
  return {
      collapsedLength1,
      collapsedLength2,
      segmentLength
  }
}
function getJointDirection(curPos, prevPos, nextPos, isTile, index, points) {
  let dir = new Vector3();
  let dir_v = new Vector3();
  let preDir = new Vector3();
  let nextDir = new Vector3();
  let divideDir = new Vector3();
  let cos = 1;
  let angleDirection;
  preDir.subVectors(curPos , prevPos).setZ(0).normalize();
  nextDir.subVectors(nextPos , curPos).setZ(0).normalize();
  divideDir.addVectors(preDir.clone().multiplyScalar(-1) , nextDir).normalize();
  if(divideDir.y < 0  || divideDir.y === 0 && divideDir.x > 0) {
      angleDirection = 'up';
  } else {
      angleDirection = 'down';
  }
  let n = new Vector3();
  n.crossVectors(preDir, nextDir).normalize();
  let firstDir = new Vector3();
  let secondDir = new Vector3();
  firstDir.crossVectors(preDir, n).normalize();
  secondDir.crossVectors(nextDir, n).normalize();
  if(divideDir.dot( firstDir) > 0) {
      firstDir = new Vector3(-firstDir.x , -firstDir.y , -firstDir.z);
  }
  if(divideDir.dot(secondDir) > 0) {
      secondDir = new Vector3(-secondDir.x , -secondDir.y , -secondDir.z);
  }
  if(nextPos.equals(curPos)) {
      dir.subVectors(curPos , prevPos).normalize();
      cos = 1;
  } else if(prevPos.equals(curPos)) {
      dir.subVectors(nextPos , curPos).normalize();
      cos = 1;
  } else {
      dir.addVectors(preDir, nextDir).normalize();
      let dir_v = new Vector3();
      dir_v.crossVectors(dir,n)
      cos = dir_v.dot(firstDir) || 1;
      if(dir.length() == 0) {
          dir.subVectors(nextPos , curPos).normalize();
          cos = 1
      }
  }
  dir_v.crossVectors(dir,n)
  dir = dir_v.clone();

  if(angleDirection === 'up') {
      if(dir.y > 0 || dir.y === 0 && dir.x < 0) {
          dir = new Vector3(-dir.x , -dir.y , -dir.z);
       }
  } else {
      if(dir.y < 0 || dir.y === 0 && dir.x > 0) {
          dir = new Vector3(-dir.x , -dir.y , -dir.z);
       }
  }
  if(dir.equals(firstDir)) {
      dir = new Vector3(-dir.x , -dir.y , -dir.z);
  }
  let clock;
  if(firstDir.x < secondDir.x || firstDir.x === secondDir.x && firstDir.y < secondDir.x) {
      clock = angleDirection === 'up' ? -1 : 1;
  } else {
      clock = angleDirection === 'up' ? 1 : -1;
  }
  return {
      angleDirection,
      cos,
      miterDir: dir,
      firstDir,
      secondDir,
      prevDir: preDir.subVectors(curPos , prevPos ),
      nextDir: nextDir.subVectors(nextPos , curPos),
      clock,
      normal: n
  }
}
function isSameSide(a,b,line) {
  let dir1 = new Vector3();
  let dir2 = new Vector3();
  dir1.crossVectors(a, line)
  dir2.crossVectors(b, line)
  if(dir1.dot(dir2) > 0) {
      return true
  } else {
      return false
  }
}

function getClock(a,b) {
    let clock = new Vector3();
    clock.crossVectors(a, b);
    return clock.z;
}
export {line}
